﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Windows.Forms;
using Assist;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Plumbing;
using Autodesk.Revit.Exceptions;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using YArchitech.Controls;
using YArchitech.LIB;
using YArchitech.MEP;
using YArchitech.ProgressBar;
using YArchitech.Revit;

namespace YArchitech.HVAC
{
	[Transaction(TransactionMode.Manual)]
	public class EnsureDiameter : IExternalCommand
	{
		public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
		{
			Transaction transaction = null;
			if (commandData == null)
			{
				throw new System.ArgumentNullException();
			}
			DialogResult dialogResult = DialogResult.OK;
			UIDocument activeUIDocument = commandData.Application.ActiveUIDocument;
			Document document = activeUIDocument.Document;
			Autodesk.Revit.DB.View activeView = activeUIDocument.ActiveView;
			Selection selection = activeUIDocument.Selection;
			if (!YJKRevitTools.ViewCheck(activeUIDocument, new List<ViewType>
			{
				1,
				2
			}))
			{
				return Autodesk.Revit.UI.Result.Cancelled;
			}
			FrmDefinePipes frmDefinePipes = new FrmDefinePipes(document);
			ProgressBarForm progressBarForm = new ProgressBarForm(6, ProgressBarStyle.Blocks, true);
			IntPtr mainWindowHandle = Process.GetCurrentProcess().MainWindowHandle;
			this._hWndRevit = new YJKWindowHandle(mainWindowHandle);
			Result result;
			try
			{
				SprinklerCalOperate sprinklerCalOperate = new SprinklerCalOperate();
				transaction = new Transaction(document, "确定并修改水管管径");
				if (dialogResult == DialogResult.OK)
				{
					dialogResult = frmDefinePipes.ShowDialog();
				}
				if (dialogResult == DialogResult.Yes)
				{
					transaction.Start();
					RevitVersionFuncs.ClearSelection(selection);
					int maxDiameter = frmDefinePipes.maxDiameter;
					int dangerId = frmDefinePipes.dangerId;
					SearchBranch searchBranch = new SearchBranch(Autodesk.Revit.DB.ElementType.Pipe, Autodesk.Revit.DB.ElementType.Sprinklers, activeUIDocument);
					searchBranch.PickFirstElement(new PipeFilter(), "请选择喷淋系统入口的水管(注:距选择点近的接口为搜索的入口)……");
					this.ShowProcessBar(progressBarForm, "搜索系统信息", true);
					searchBranch.DoSearch();
					ElementNode listRoot = searchBranch.GetListRoot();
					List<ChangeElements> listChangeElem = null;
					List<FamilyInstance> list = null;
					sprinklerCalOperate.GetAndChangeDiameterPipes(listRoot, frmDefinePipes.listPtNum, frmDefinePipes.maxDiameter, dangerId, frmDefinePipes.K, frmDefinePipes.minDiameter, frmDefinePipes.GetBeReflectedKValue(), ref listChangeElem, ref list);
					FamilyInstance familyInstance = null;
					this.GetSprinkler(listRoot, ref familyInstance);
					if (familyInstance == null)
					{
						YJKMessageBox.Show("找不到喷头族！");
						transaction.RollBack();
						return Autodesk.Revit.UI.Result.Failed;
					}
					int sprinklerDiameter = PipeConfigurationManagement.GetSprinklerDiameter(familyInstance.Symbol);
					this.ShowProcessBar(progressBarForm, "删除系统内特定管件", false);
					if (list != null && list.Count > 0)
					{
						foreach (FamilyInstance elem in list)
						{
							document.DeleteElement(elem);
						}
					}
					document.Regenerate();
					this.ShowProcessBar(progressBarForm, "修改管道管径", false);
					int num = 0;
					if (sprinklerCalOperate.ListPipeDiameters != null && sprinklerCalOperate.ListPipeDiameters.Count > 0)
					{
						foreach (PipeDiameter pipeDiameter in sprinklerCalOperate.ListPipeDiameters)
						{
							if (pipeDiameter.PipeElement != null && pipeDiameter.Diameter > 0.0)
							{
								Parameter parameter = pipeDiameter.PipeElement.GetParameter(BuiltInParameter.RBS_PIPE_DIAMETER_PARAM);
								if (parameter != null && parameter.Set(pipeDiameter.Diameter / 304.8))
								{
									num++;
								}
							}
						}
						document.Regenerate();
					}
					if (num <= 0)
					{
						YJKMessageBox.Information("没有搜到需要修改管道，请重新选择。");
						transaction.RollBack();
						progressBarForm.Dispose();
						return Autodesk.Revit.UI.Result.Succeeded;
					}
					YJKMessageBox.Information("共确定并修改" + num + "条水管。");
					this.ShowProcessBar(progressBarForm, "重新连接管道", false);
					document.Regenerate();
					sprinklerCalOperate.ReConnPipes(listRoot.Element as Pipe, listChangeElem, sprinklerDiameter, frmDefinePipes.blThreeFour);
					document.Regenerate();
					this.ShowProcessBar(progressBarForm, "设置管件显示", false);
					SearchBranch searchBranch2 = new SearchBranch(Autodesk.Revit.DB.ElementType.Pipe, Autodesk.Revit.DB.ElementType.Sprinklers, activeUIDocument);
					searchBranch2.DoSearch(listRoot);
					listRoot = searchBranch2.GetListRoot();
					List<FamilyInstance> list2 = null;
					List<FamilyInstance> list3 = null;
					sprinklerCalOperate.ReGetEblowTeeAndTransation(listRoot, ref list2, ref list3);
					foreach (FamilyInstance familyInstance2 in list2)
					{
						if (familyInstance2.Symbol.Family.Name.Contains("空白"))
						{
							List<Connector> elementAllConnector = YJKRevitTools.GetElementAllConnector(familyInstance2);
							bool flag = false;
							foreach (Connector connector in elementAllConnector)
							{
								foreach (FamilyInstance familyInstance3 in list3)
								{
									using (List<Connector>.Enumerator enumerator5 = YJKRevitTools.GetElementAllConnector(familyInstance3).GetEnumerator())
									{
										while (enumerator5.MoveNext())
										{
											if (enumerator5.Current.Origin.DistanceTo(connector.Origin) < 0.1)
											{
												YJKRevitTools.SetAnnotationProportation(familyInstance3, true);
												flag = true;
												break;
											}
										}
									}
									if (flag)
									{
										break;
									}
								}
								if (flag)
								{
									break;
								}
							}
						}
					}
					this.ShowProcessBar(progressBarForm, "标注管道", false);
					CommonIndependentTag commonIndependentTag = new CommonIndependentTag();
					double fontHeight = frmDefinePipes.GetFontHeight();
					foreach (PipeDiameter pipeDiameter2 in sprinklerCalOperate.ListPipeDiameters)
					{
						if (pipeDiameter2.PipeElement.IsValidObject)
						{
							Pipe pipeElement = pipeDiameter2.PipeElement;
							if (pipeElement != null)
							{
								double distanceToPipeLine = frmDefinePipes.GetDistanceToPipeLine();
								double minDiameter = (double)frmDefinePipes.GetMarkMinDiameter();
								bool beDeletedTag = frmDefinePipes.GetBeDeletedTag();
								commonIndependentTag.MarkSprinklerPipe(pipeElement, fontHeight, distanceToPipeLine, minDiameter, beDeletedTag);
							}
						}
					}
					document.Regenerate();
					transaction.Commit();
					if (fontHeight > 0.1)
					{
						commonIndependentTag.EditFamilyFontHeight(document, fontHeight);
					}
					new MarkOperation().SetActiveDocAllLoadedTags(document, true);
					dialogResult = DialogResult.Cancel;
				}
				if (dialogResult == DialogResult.Cancel)
				{
					frmDefinePipes.Dispose();
				}
				result = Autodesk.Revit.UI.Result.Succeeded;
			}
			catch (Autodesk.Revit.Exceptions.OperationCanceledException)
			{
				result = Autodesk.Revit.UI.Result.Succeeded;
			}
			catch (Exception ex)
			{
				message = ex.Message;
				result = Autodesk.Revit.UI.Result.Failed;
			}
			finally
			{
				if (transaction != null)
				{
					TransactionStatus status = transaction.GetStatus();
					if (status == 1)
					{
						transaction.Commit();
					}
					else if (status == 5)
					{
						transaction.RollBack();
					}
				}
				if (progressBarForm != null)
				{
					progressBarForm.Dispose();
				}
			}
			return result;
		}

		private void ShowProcessBar(ProgressBarForm progressBar, string titleStr, bool beFirst = false)
		{
			progressBar.Text = titleStr;
			if (beFirst)
			{
				progressBar.ShowInTaskbar = false;
				progressBar.Show(this._hWndRevit);
				return;
			}
			progressBar.RefreshProgressBar();
		}

		private void GetSprinkler(ElementNode en, ref FamilyInstance fi)
		{
			if (en == null)
			{
				return;
			}
			if (en.Element is FamilyInstance)
			{
				FamilyInstance familyInstance = en.Element as FamilyInstance;
				if (familyInstance.Category.Id.IntegerValue == -2008099)
				{
					fi = familyInstance;
				}
				else
				{
					this.GetSprinkler(en.Next, ref fi);
				}
			}
			else
			{
				this.GetSprinkler(en.Next, ref fi);
			}
			if (en.SubElementNode != null)
			{
				foreach (ElementNode en2 in en.SubElementNode)
				{
					this.GetSprinkler(en2, ref fi);
				}
			}
		}

		public YJKWindowHandle _hWndRevit;
	}
}
